#include <stdlib.h>
#include <sys/time.h>
#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <termios.h>

#include "nbc.h"

#define BAUDRATE B9600   


char   g_dev[16];

int    g_serial_delay = 500;
struct termios tio;
int    tty_fd, flags;

int processData(char* fname);
//===============================
void readDeviceName()
//===============================
{
  FILE  *in,*out;
  int   n = 0;
  char  line[128];
  char  temps[12];

  system("ls /dev | grep ACM > device.nbc"); 
  in = fopen("device.nbc","r");
  if(in == NULL)
    {
      printf("No ACM device information file\n");
    }
  else
    {
      while (fgets(line,sizeof line,in) != NULL)
	{ 
          n++;
	  if(strstr(line,"ttyACM") != NULL)sscanf(line,"%s",temps);
	  strcpy(g_dev,"/dev/");
	  strcat(g_dev,temps);
	}
      fclose(in);
    }

  if(n > 1)printf("Multiple ACM devices found - check Arduino connection\n");

  if(n == 0)
  {
  system("ls /dev | grep USB > device.nab"); 
  in = fopen("device.nab","r");
  if(in == NULL)
    {
      printf("No USB device information file\n");
    }
  else
    {
      while (fgets(line,sizeof line,in) != NULL)
	{ 
      n++;
	  if(strstr(line,"ttyUSB") != NULL)sscanf(line,"%s",temps);
	  strcpy(g_dev,"/dev/");
	  strcat(g_dev,temps);
	}
      fclose(in);
    }

  if(n > 1)printf("Multiple USB devices found - check Arduino connection\n");
  }
  if(n == 0)
  {
	  printf("No device found - check Arduino connection\n");
	  exit(0);
  }
}

//===============================
void delay(int t)
//===============================
{
  t = t*1000; // convert to ms
  usleep(t);
} 
//===============================
void readSerial()
//===============================
{
 
  unsigned char c='D';
  unsigned char z='D';
  int i,temp1,temp2;
  unsigned char inres[240];

     
  int nn = 0;
  int start = 0;
  while (c != ';')
    {
      if (read(tty_fd,&c,1)>0) 
        {
		  if(start == 1)
		  {
            if(g_debug > 3)printf("<%c>",c);
            g_ul_data[nn] = c;
            nn++;
	      }
	      if(c=='*')start = 1;
        }
    }
  c = ' ';
  g_ul_data[nn-1] = '\0';
 
} 
//===============================
void writeFile()
//===============================
{
  FILE  *out;
  char fname[80],stemp[80];
  int checksum=999,mid=0,sid=0,temp;
  
  sscanf(g_ul_data,"%d %d %d",&mid,&sid,&checksum);
  temp = checksum - mid - sid;
  if(temp == 0)
  {
    if(mid == NABTON_DATA || mid == NABTON_INFO)
    {
      if(mid == NABTON_INFO)
      {
		  sprintf(stemp," %d",g_serial_delay);
		  strcat(g_ul_data,stemp);
	  }
      g_rrno++;
      if(g_rrno > MAX_RRNO)g_rrno = 0;
      sprintf(fname,"ul_data_%d.nbc",g_rrno);
      out = fopen(fname,"w");
      fprintf(out,"%s",g_ul_data);
      fclose(out);
      if(g_debug >0)printf("Uplink [%s] ",g_ul_data);
    }
  }
  else
    if(g_debug >0)printf("Checksum error [%s] ",g_ul_data);
} 
//===============================
int readFile()
//===============================
{
  FILE  *in;
  char  line[128],ff[128],syscmd[80];
  
  system("ls dl_data*.nbc > dl_flist.nbc 2>&1");
  
  in = fopen("dl_flist.nbc","r");
  if(in == NULL)
  {
      printf("No dl_flist.nbc\n");
      return(0);
  }
  while(fgets(line,sizeof line,in) != NULL)
  { 
     //printf("process %s",line);
     sscanf(line,"%s",ff);
     processData(ff);
     sprintf(syscmd,"rm -f %s",ff);
     system(syscmd);
  }
  fclose(in);
 
  return(1);
} 
//===============================
void writeSerial()
//===============================
{
	char stemp[500];
	sprintf(stemp,"* %s ;",g_dl_data);
    if(g_debug > 0)printf("Downlink %s ",stemp);
    write(tty_fd,stemp,strlen(stemp)); 
    strcpy(g_dl_data," ");
} 
//===============================
int processData(char* fname)
//===============================
{
  FILE  *in;
  char  line[128],stemp[40];
  int action=0,mid,sid;

  strcpy(g_dl_data," ");

  in = fopen(fname,"r");
  if(in == NULL)
  {
      return(0);
  }
  while(fgets(line,sizeof line,in) != NULL)
  { 
   if(g_debug > 2)printf("%s %s ",fname,line);
   if(g_debug > 1)
   {
	   if(strstr(line,"NBC_") != NULL)printf(" %s ",line);
   }
   //Serial gateway actions
   if(strstr(line,"NBC_SERIAL_DELAY") != NULL)
   {
   	   sscanf(line,"%d %d %s %d",&mid,&sid,stemp,&g_serial_delay);
	   if(g_debug > 0)printf(" NBC_SERIAL_DELAY = %d ",g_serial_delay);
   }
   if(strstr(line,"NBC_SERIAL_DEBUG") != NULL)
   {
	   sscanf(line,"%d %d %s %d",&mid,&sid,stemp,&g_debug);
	   printf(" NBC_SERIAL_DEBUG = %d ",g_debug);
   }
   
   //Serial device actions
   if(strstr(line,"NBC_REPORT_CONF") != NULL)action = 1;
   if(strstr(line,"NBC_DEVICE_DELAY") != NULL)action = 1;
   if(strstr(line,"NBC_STEPPER_CTRL") != NULL)action = 1;
   //if(strstr(line,"new nabton command") != NULL)action =1 ;
   
     if(strstr(line,"STEPPER_CTRL") != NULL)action =1;
     
     if(action==1)
     {
		strcpy(g_dl_data,line);
		writeSerial();
	 }
  }
  fclose(in);
}
//===============================
int main(int argc, char **argv)
//===============================
{   
  g_rrno = 0;
  readDeviceName();
  printf(  "Device....: %s\n",g_dev);

  memset(&tio,0,sizeof(tio));
  tio.c_iflag=0;
  tio.c_oflag=0;
  tio.c_cflag=CS8|CREAD|CLOCAL;  // 8n1, see termios.h for more information
  tio.c_lflag=0;
  tio.c_cc[VMIN]=1;
  tio.c_cc[VTIME]=5;
  if((tty_fd = open(g_dev , O_RDWR | O_NONBLOCK)) == -1)
  {
        if(g_debug > 0)printf("GWY: Waiting for Arduino connection...\n"); 
  }
  else
  {
        if(g_debug > 0)printf("GWY: Connected to Arduino %s\n ",g_dev); 
        cfsetospeed(&tio,BAUDRATE);    
        cfsetispeed(&tio,BAUDRATE);      
        tcsetattr(tty_fd,TCSANOW,&tio);
        tcsetattr(tty_fd, TCSAFLUSH, &tio);
  }            
 
  while(1)
  {
	  readSerial();
	  writeFile();
	  if(g_debug > 0)printf("\n(%d,%d)",g_serial_delay,g_debug);
	  delay(g_serial_delay);
	  readFile();
	  //writeSerial();
  }
  
}
